#ifndef DEPLACEMENT_H
#   define DEPLACEMENT_H


#include "base_donnees.h"
#include "resume_saisie.h"
#include "carte_zone.h"
#include "def_etat_bataille.h"




/**
 * \struct coordonnees deplacement.h
 * Structure permettant de stocker des coordonnees
 */
struct coordonnees
{
    /** Coordonnee horizontale */
    int x;
    /** Coordonnee verticale */
    int y;
};



/**
 * \struct tab_file deplacement.h
 * Tableau qui permet de simuler une file, avec l'aide
 * d'un second tableau du meme type
 */
struct tab_file
{
    struct coordonnees tab[TAILLE_TAB_FILE];
    unsigned int nb_elements;
};



/**
 * \struct elem_tab_deplacement deplacement.h
 * Permet de faire correspondre a une position hypothetique la longueur du
 * plus court chemin trouve jusqu'a cette position, ainsi que le dernier
 * deplacement que l'on aura effectue en empruntant ce chemin
 */
struct elem_tab_deplacement
{
    /** NEUTRE, HAUT, DROITE, BAS, ou GAUCHE */
    char direction;
    /**
     * Longueur du meilleur chemin trouve.\n
     * Attention : on utilise la constante INF,
     * qui represente l'infini et qui vaut -1
     */
    int distance;
};



/**
 * \struct tableaux_deplacement deplacement.h
 * Ensemble de tableaux permettant aux ennemis de choisir une direction
 * lors de leurs deplacements
 */
struct tableaux_deplacement
{
    /**
     * tableau conservant les chemins les plus courts
     * trouves pour acceder aux positions environnantes.\n
     * Ce pointeur pointe vers le centre du tableau
     */
    struct elem_tab_deplacement* tab_positions;
    /** pointeur vers la premiere case du tableau de positions */
    struct elem_tab_deplacement* origine_tab_positions;
    /**
     * positions (absolues) ideales pour les
     * ennemis qui attaquent a distance
     */
    struct coordonnees positions_ideales[4];
    /** premier des deux tableaux servant a simuler une file de cas a traiter */
    struct tab_file tab_a;
    /** deuxieme des deux tableaux servant a simuler une file de cas a traiter */
    struct tab_file tab_b;
    /** pointeur vers le tableau dans lequel on ecrit */
    struct tab_file* ecriture;
    /** pointeur vers le tableau dans lequel on lit */
    struct tab_file* lecture;
};




/**
 * \fn void modifier_coordonnees(unsigned int* x, unsigned int* y, const char direction)
 * \brief Modifie des coordonnees en fonction d'une direction
 *
 * \param[in] x Adresse de la coordonnee horizontale
 * \param[in] y Adresse de la coordonnee verticale
 * \param[in] direction La direction du deplacement
 *
 * Les valeurs "efficaces" de direction sont les constantes HAUT, DROITE,
 * BAS, GAUCHE. Toute autre valeur ne provoquera aucun changement.
 */
void modifier_coordonnees(unsigned int* x, unsigned int* y, const char direction);



/**
 * \fn void deplacer_joueur(struct etat_bataille* bataille, const struct carte_zone* carte,
                            const struct resume_saisie* saisie, const struct base_donnees* donnees)
 * \brief Met a jour les coordonnees et le score de deplacement du joueur en
 *        fonction des souhaits de celui-ci et des obstacles
 *
 * \param[in,out] bataille L'adresse de l'etat de la bataille
 * \param[in] carte L'adresse de la carte de la zone actuelle
 * \param[in] saisie Le resume des touches pressees par le joueur
 * \param[in] donnees L'adresse d'une base_donnees correctement remplie
 */
void deplacer_joueur(struct etat_bataille* bataille, const struct carte_zone* carte,
                     const struct resume_saisie* saisie, const struct base_donnees* donnees);



/**
 * \fn void deplacer_projectiles(struct carte_zone* carte,
                                 struct etat_bataille* bataille,
                                 const struct base_donnees* donnees)
 * \brief Fait se deplacer tous les projectiles en cours de vol
 *
 * \param[in,out] carte L'adresse de la carte de la zone actuelle
 * \param[in,out] bataille L'adresse de l'etat de la bataille qui se deroule
 * \param[in] donnees L'adresse d'une base_donnees correctement remplie
 *
 * C'est dans cette fonction que sont geres les degats occasionnes par les
 * projectiles.
 */
void deplacer_projectiles(struct carte_zone* carte,
                          struct etat_bataille* bataille,
                          const struct base_donnees* donnees);



/**
 * \fn void deplacer_ennemis(struct tableaux_deplacement* tabs,
                             struct etat_bataille* bataille,
                             const struct carte_zone* carte,
                             const struct base_donnees* donnees)
 * \brief Permet aux ennemis de se deplacer
 *
 * \param[in,out] tabs L'adresse de tableaux de deplacement correctement initialises
 * \param[in,out] bataille L'adresse de l'etat de la bataille
 * \param[in] carte L'adresse de la carte de la zone actuelle
 * \param[in] donnees L'adresse d'une base_donnees correctement remplie
 */
void deplacer_ennemis(struct tableaux_deplacement* tabs,
                      struct etat_bataille* bataille,
                      const struct carte_zone* carte,
                      const struct base_donnees* donnees);



/**
 * \fn void init_tabs_deplacement(struct tableaux_deplacement* tabs,
                                  const struct etat_bataille* bataille,
                                  const struct carte_zone* carte)
 * \brief Initialise des tableaux de deplacement
 *
 * \param[out] tabs L'adresse des tableaux a initialiser
 * \param[in] bataille L'adresse de l'etat de la bataille
 * \param[in] carte L'adresse de la carte de la zone
 */
void init_tabs_deplacement(struct tableaux_deplacement* tabs,
                           const struct etat_bataille* bataille,
                           const struct carte_zone* carte);



/**
 * \fn void reinit_tabs_deplacement(struct tableaux_deplacement* tabs)
 * \brief Prepare des tableaux de deplacement a etre utilises
 *        pour un nouvel ennemi
 *
 * \param[in,out] tabs L'adresse des tableaux a reinitialiser
 *
 * \warning Cette fonction doit etre appelee pour
 *          chaque ennemi, meme le premier !
 */
void reinit_tabs_deplacement(struct tableaux_deplacement* tabs);



/**
 * \fn void detruire_tabs_deplacement(struct tableaux_deplacement* tabs)
 * \brief Libere la memoire allouee pour des tableaux de deplacement
 */
void detruire_tabs_deplacement(struct tableaux_deplacement* tabs);



/**
 * \fn void echanger_tabs_deplacement(struct tableaux_deplacement* tabs)
 * \brief Echange les tableaux de lecture et d'ecriture
 *
 * \param[in,out] tabs L'adresse des tableaux de
 *                     deplacement concernes
 */
void echanger_tabs_deplacement(struct tableaux_deplacement* tabs);



#endif /* DEPLACEMENT_H */
